<template>
  <div :class="`table-section ${wrapClass}`">
      <!-- :height="tableHeight" -->
    <el-table
      ref="tableRef"
      :row-key="rowKey"
      :data="data"
      :show-summary="showSummary"
      :summary-method="summaryMethod"
      :default-sort="defaultSort"
      :showHeader="showHeader"
      :border="border"
      :size="tableSize"
      :header-cell-class-name="headerCellClass"
      :row-class-name="rowClassName"
      @selection-change="handleSelectionChange"
      @sort-change="handleSortChange"
    >
      <el-table-column  v-if="selectionType && columns.length" type="selection" align="center" />
      <el-table-column
        v-for="(column, index) in columns"
        :column-key="column.columnKey || column.prop"
        :prop="column.prop"
        :label="column.label"
        :width="column.width"
        :min-width="column.minWidth"
        :align="column.align"
        :fixed="column.fixed"
        :sortable="column.sortable"
        :sort-by="column.sortBy"
        :sort-orders="column.sortOrders"
        :render-header="column.renderHeader"
        :class-name="column.className || ''"
        :label-class-name="column.labelClassName || ''"
      >
        <template #default="scope">
          <my-render v-if="column.render" :index="scope.$index" :row="scope.row" :render="column.render" />
          <!-- <div v-if="column.render">{{ column.render({row: scope.row, index: scope.$index}) }}</div> -->
          <div v-else> {{ scope.row[column.prop]}} </div>
        </template>
      </el-table-column>
    </el-table>
    <div class="pagination-container" v-if="isShowPagination">
      <el-pagination
        :current-page="pagination.current"
        :page-size="pagination.size"
        :total="pagination.total"
        :page-sizes="pageSizes"
        layout="total, sizes, prev, pager, next, jumper"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
  </div>
</template>

<script setup lang="ts">
import type { ElTable, ElTableColumn } from 'element-plus'
import type { TableColumnCtx } from 'element-plus/es/components/table/src/table-column/defaults'
import { onBeforeUnmount, onMounted, PropType, ref } from 'vue';
import MyRender from './MyRender.vue';


const tableRef = ref<InstanceType<typeof ElTable>>()

type TableColumnFix<T> = TableColumnCtx<T> & {
  render?: boolean
}

type PaginationOption = {
  current: number
  size: number
  total: number
}

const props = defineProps({
  loading: {
    type: Boolean,
    default: true
  },
  wrapClass: {
    type: String,
    default: '',
  },
  tableSize: {
    type: String,
    default: 'small',
  },
  headerCellClass: {
    type: [String, Function],
    default: '',
  },
  rowClassName: {
    type: [String, Function],
    default: '',
  },
  rowKey: {
    type: [String, Function],
    default: 'index',
  },
  data: Array,
  selectionType: {
    type: [Boolean, Function],
    default: false,
  },
  columns: {
    type: Array as PropType<Array<any>>,
    default: () => []
  },
  tableHeight: {
    type: [String, Number]
  },
  showSummary: {
    type: Boolean,
    default: false,
  },
  border: {
    type: Boolean,
    default: true,
  },
  defaultSort: {
    type: Object,
  },
  showHeader: {
    type: Boolean,
    default: true,
  },
  isCustomHeight: {
    type: Boolean,
    default: false,
  },
  customHeight: {
    type: String,
    default: '400px',
  },
  extraHeight: {
    type: Number,
    default: 0,
  },
  pageSizes: {
    type: Array,
    default: () => {
      return [25, 100, 200, 250];
    },
  },
  sumData: {
    type: Array as PropType<Array<TableColumnFix<any>>>,
  },
  sortOrders: {
    type: Array,
    default: () => {
      return ['ascending', 'descending', null]
    }
  },
  isShowPagination: {
    type: Boolean,
    default: true,
  },
  pagination: {
    type: Object as PropType<PaginationOption>,
    default: () => {
      return {
        total: 0,
        current: 1,
        size: 25,
      };
    },
  },
})

const emit = defineEmits(['sortChange', 'selectionChange', 'change'])

// 合并显示行
interface SummaryMethodProps<T> {
  columns: TableColumnFix<T>[]
  data: T[]
}
const summaryMethod = (param: SummaryMethodProps<any>) => {
  const { columns } = param
  if (props.showSummary) {
    const sum: any[] = []
    if (props.sumData) {
      columns.forEach((col, colIndex) => {
        if (colIndex === 0) {
          sum.push((props.sumData as any[])[colIndex])
        } else {
          sum[colIndex] = (props.sumData as any[])[colIndex]
        }
      })
    }
    return [sum]
  }
}
// 多选
const handleSelectionChange = (selection: any[]) => {
  emit('selectionChange', selection)
}

// 排序
interface SortProps<T> {
  column: TableColumnFix<T>
  prop: String
  order: String
}

const handleSortChange = (param: SortProps<any>) => {
  const { column, prop, order } = param
  emit('change', { column, prop, order })
}

// 切换条数
const handleSizeChange = (val: number) => {
  props.pagination.current = 1
  props.pagination.size = val
  handleCurrentChange(props.pagination.size)
}

const handleCurrentChange = (val: number) => {
  const { size } = props.pagination
  emit('change', { current: val, size })
}

// 高度自适应
const tableHeight = ref<string | number>(400)
const computeTableHeight = () => {
  if (props.isCustomHeight) {
    tableHeight.value = props.customHeight
  } else {
    tableHeight.value = window.innerHeight - 70 - (!props.isShowPagination ? 0 : 40) - props.extraHeight
  }
}
computeTableHeight()

onMounted(() => {
  window.addEventListener('resize', computeTableHeight)
})

onBeforeUnmount(() => {
  window.removeEventListener('resize', computeTableHeight)
})


</script>

